package com.ziyun.erp.modules.service.service.impl;

import com.utility.StringUtils;
import com.ziyun.erp.common.e.service.ServiceRefundStatusEnum;
import com.ziyun.erp.common.e.service.ServiceStatusEnum;
import com.ziyun.erp.common.e.service.ServiceTypeEnum;
import com.ziyun.erp.modules.capital.entity.MerchantOrderAccountEntity;
import com.ziyun.erp.modules.capital.service.MerchantOrderAccountService;
import com.ziyun.erp.modules.order.entity.OrderInfoEntity;
import com.ziyun.erp.modules.order.entity.UserPaymentEntity;
import com.ziyun.erp.modules.order.service.OrderInfoService;
import com.ziyun.erp.modules.order.service.UserPaymentService;
import com.ziyun.erp.modules.production.entity.ErpOrderItemEntity;
import com.ziyun.erp.modules.service.entity.ServiceReceiveGoodsEntity;
import com.ziyun.erp.modules.service.entity.ServiceRefundsEntity;
import com.ziyun.erp.modules.service.service.ServiceReceiveGoodsService;
import com.ziyun.erp.modules.service.service.ServiceRefundsService;
import com.ziyun.erp.modules.service.vo.ServiceOrderInfoVo;
import com.ziyun.erp.modules.service.vo.ServiceRegisterVo;
import io.renren.common.exception.RRException;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.common.utils.StringUtil;
import io.renren.modules.sys.entity.SysUserEntity;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

import com.ziyun.erp.modules.service.dao.ServiceRegisterDao;
import com.ziyun.erp.modules.service.entity.ServiceRegisterEntity;
import com.ziyun.erp.modules.service.service.ServiceRegisterService;
import org.springframework.transaction.annotation.Transactional;


@Service("serviceRegisterService")
public class ServiceRegisterServiceImpl extends ServiceImpl<ServiceRegisterDao, ServiceRegisterEntity> implements ServiceRegisterService {

    @Autowired
    private ServiceReceiveGoodsService serviceReceiveGoodsService;

    @Autowired
    private ServiceRefundsService serviceRefundsService;

    @Autowired
    private OrderInfoService orderInfoService;

    @Autowired
    private UserPaymentService userPaymentService;

    @Autowired
    private MerchantOrderAccountService merchantOrderAccountService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        Page<ServiceRegisterEntity> page = new Query<ServiceRegisterEntity>(params).getPage();

        page.setRecords(this.baseMapper.selectServicRegisterPage(page, params));

     /*   Page<ServiceRegisterEntity> page = this.selectPage(
                new Query<ServiceRegisterEntity>(params).getPage(),
                new EntityWrapper<ServiceRegisterEntity>()
                .eq(StringUtil.isNotNull(params.get("srOrderId")) && StringUtil.isNotEmpty(params.get("srOrderId").toString()),"sr_order_id",params.get("srOrderId"))
                .eq(StringUtil.isNotNull(params.get("srStatus")) && StringUtil.isNotEmpty(params.get("srStatus").toString()) ,"sr_status",params.get("srStatus"))
        );*/

        return new PageUtils(page);
    }

    /**
     * 售后登记
     * @param serviceRegister
     */
    @Override
    @Transactional
    public void saveRegister(ServiceRegisterVo serviceRegister) {
        //开始处理业务 先判断 sr_order_id 是否已经存在
        int count =  this.baseMapper.selectCount(new EntityWrapper<ServiceRegisterEntity>().
                                eq("sr_order_id",serviceRegister.getServiceRegister().getSrOrderId()));

        if(count >0){
            throw new RRException("该单据已经存在售后单!");
        }

        /*
           判断当前订单状态
           1. 互动订单或者完成订单
           2. 满足已经支付
           3. 满足 未提现
        */
        OrderInfoEntity orderInfo =  this.orderInfoService.selectById(serviceRegister.getServiceRegister().getSrOrderId());
        if (orderInfo.getStatus().equals("active") || orderInfo.getStatus().equals("finish")) {
            //正常状态
        }else {
            throw new RRException("当前订单状态为" +orderInfo.getStatus() +"不支持发起售后!");
        }

        if (!orderInfo.getPayStatus().equals("1")){
            throw new RRException("该订单未支付!");

        }

        int countCash =  this.merchantOrderAccountService.selectCount(new EntityWrapper<MerchantOrderAccountEntity>()
                                                        .eq("order_id", serviceRegister.getServiceRegister().getSrOrderId())
                                                        .in("fund_state", new Integer[]{1,2}));
        if (countCash >0){
            throw new RRException("该单据已经提现!");
        }


        //1.首先判断售后类型
        Integer srType = serviceRegister.getServiceRegister().getSrType();

        if (srType.equals(ServiceTypeEnum.SERVICE_REFUND.toInt())){ //仅退款
            //处理公共字段
            ServiceRegisterEntity serviceRegisterCommon = this.serviceRefundCommon(serviceRegister.getServiceRegister());
            //处理退款业务
            this.serviceRefundTK(serviceRegisterCommon, serviceRegister.getServiceRegister(), serviceRegister.getServiceRefunds());
        }else if(srType.equals(ServiceTypeEnum.SERVICE_RETURN_REFUND.toInt())){ //退货退款
            //处理公共字段
            ServiceRegisterEntity serviceRegisterCommon = this.serviceRefundCommon(serviceRegister.getServiceRegister());
            //处理退货业务
            this.serviceRefundTH(serviceRegisterCommon,serviceRegister.getServiceRegister(),serviceRegister.getOrderItemList(), serviceRegister.getServiceRefunds());

        }else if (srType.equals(ServiceTypeEnum.SERVICE_EXCHANGE_GOODS.toInt())){//换货

        }else if (srType.equals(ServiceTypeEnum.SERVICE_REISSUE.toInt())){//补发

        }

    }

    @Override
    public ServiceOrderInfoVo selectServiceOrderInfo(String srOrderId) {
        return this.baseMapper.selectServiceOrderInfo(srOrderId);
    }

    /**
     * 售后审核
     * @param serviceRegister
     */
    @Override
    public void check(ServiceRegisterEntity serviceRegister) {
        // 查询当前售后单状态
        ServiceRegisterEntity temp =  this.selectById(serviceRegister.getSrId());
        if (temp == null){
            throw new RRException("未查询到当前售后单!");
        }

        if(temp.getSrStatus().intValue() !=1 ){
            throw new RRException("当前售后单不支持当前操作!");
        }


        // 先判断操作类型
        if (serviceRegister.getSrStatus().intValue() ==  ServiceStatusEnum.SERVICE_CLOSED.toInt()){ //审核驳回
            // 更新 关闭订单即可
            serviceRegister.setSrResponsibility(null);
            this.baseMapper.updateById(serviceRegister);
        }else if (serviceRegister.getSrStatus().intValue() ==  ServiceStatusEnum.SERVICE_CHECKED.toInt()){ //审核通过
            // 先判断售后类型
            if(serviceRegister.getSrType().intValue() == ServiceTypeEnum.SERVICE_REFUND.toInt()){
                // 涉及到退款业务 更新判定责任
                this.baseMapper.updateById(serviceRegister);

                //更新售后打款单状态
                ServiceRefundsEntity serviceRefunds = new ServiceRefundsEntity();
                serviceRefunds.setSrRefundStatus(ServiceRefundStatusEnum.SERVICE_RETURN_REFUND.toInt());
                serviceRefunds.setSrSrId(serviceRegister.getSrId());
                serviceRefundsService.update(serviceRefunds, new EntityWrapper<ServiceRefundsEntity>().
                        eq("sr_sr_id",serviceRegister.getSrId()));

            }
            // todo 其它售后类型

        }else{
            throw new RRException("当前售后单 不支持该操作!");
        }


    }

    /**
     * 生成售后单号
     * @return
     */
    private String generateId (){
        String id = String.valueOf(System.currentTimeMillis());
        int ran = (int)(Math.random()*900)+100;
        id = id + ran;
        return id;
    }

    /**
     * 售后登记公共字段
     * @param serviceRegister
     * @return
     */
    private ServiceRegisterEntity serviceRefundCommon(ServiceRegisterEntity serviceRegister){
        //生成ID
        String srCode = generateId();

        Long userId = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUserId();


        //组装数组
        ServiceRegisterEntity serviceRegisterTemp = new ServiceRegisterEntity();
        serviceRegisterTemp.setSrCode(srCode);
        serviceRegisterTemp.setSrStatus(ServiceStatusEnum.SERVICE_WAIT_CHECK.toInt());
        serviceRegisterTemp.setSrName(serviceRegister.getSrName());
        serviceRegisterTemp.setSrType(serviceRegister.getSrType());
        serviceRegisterTemp.setSrOrderId(serviceRegister.getSrOrderId());
        serviceRegisterTemp.setSrReason(serviceRegister.getSrReason());
        serviceRegisterTemp.setSrOtherReason(serviceRegister.getSrOtherReason());
        serviceRegisterTemp.setSrRemark(serviceRegister.getSrRemark());
        serviceRegisterTemp.setSrCreateName(userId.toString());
        serviceRegisterTemp.setSrCreateTime(new Date());

        //插入数据库
        return serviceRegisterTemp;
    }

    /**
     * 仅退款业务
     * @param serviceRegisterCommon
     * @param serviceRegister
     * @return
     */
    private void serviceRefundTK(ServiceRegisterEntity serviceRegisterCommon, ServiceRegisterEntity serviceRegister, ServiceRefundsEntity serviceRefunds){

        ServiceRegisterEntity serviceRegisterTemp = serviceRegisterCommon;

        this.handleRefundPath(serviceRefunds);

        // 插入售后主表
        this.insert(serviceRegisterTemp);
        // 插入退款表
        serviceRefunds.setSrSrId(serviceRegisterTemp.getSrId());
        serviceRefunds.setSrRefundStatus(ServiceStatusEnum.SERVICE_WAIT_CHECK.toInt());
        serviceRefunds.setSrCreateTime(serviceRegisterTemp.getSrCreateTime());
        serviceRefunds.setSrCreateName(serviceRegisterTemp.getSrCreateName());
        serviceRefundsService.insert(serviceRefunds);


    }

    /**
     * 退货 退款业务
     * @param serviceRegisterCommon
     * @param serviceRegister
     * @return
     */
    private void serviceRefundTH(ServiceRegisterEntity serviceRegisterCommon, ServiceRegisterEntity serviceRegister ,List<ErpOrderItemEntity> orderItemList,ServiceRefundsEntity serviceRefunds){
        if (orderItemList.size() == 0){
            throw new RRException("请选择退货商品!");
        }

        ServiceRegisterEntity serviceRegisterTemp = serviceRegisterCommon;
        //处理退款方式相关数据
        this.handleRefundPath(serviceRefunds );

        //处理退货相关数据
        Integer srFreightForm = serviceRegister.getSrFreightForm();
        if (srFreightForm == null) {
            throw new RRException("请选择运费形式!");
        }

        if (srFreightForm != 1 && serviceRegister.getSrFreightAmount() == null ){
            throw new RRException("请填写运费金额!");
        }
        serviceRegisterTemp.setSrFreightForm(srFreightForm);
        serviceRegisterTemp.setSrFreightAmount(serviceRegister.getSrFreightAmount());

        if(serviceRegister.getSrReturnStockId() == null){
            throw new RRException("请选择入库仓库!");
        }
        serviceRegisterTemp.setSrReturnStockId(serviceRegister.getSrReturnStockId());

        //插入主表
        this.insert(serviceRegisterTemp);

        // 插入退款表
        serviceRefunds.setSrSrId(serviceRegisterTemp.getSrId());
        serviceRefunds.setSrRefundStatus(ServiceRefundStatusEnum.SERVICE_REFUND.toInt());
        serviceRefunds.setSrCreateTime(serviceRegisterTemp.getSrCreateTime());
        serviceRefunds.setSrCreateName(serviceRegisterTemp.getSrCreateName());
        serviceRefundsService.insert(serviceRefunds);


        // 处理退款商品
        List<ServiceReceiveGoodsEntity> serviceReceiveGoodsList = this.serviceReceiveGoods(serviceRegisterTemp,orderItemList);

        //批量插入退款商品
        this.serviceReceiveGoodsService.insertBatch(serviceReceiveGoodsList);



    }

    /**
     * 处理退款方式
     * @param serviceRefunds
     */
    private void handleRefundPath (ServiceRefundsEntity serviceRefunds){
        // 获取退款方式
        Integer srRefundPath  = serviceRefunds.getSrRefundPath();


        if(srRefundPath == null){
            throw new RRException("请选择退款路径!");
        }

        if(srRefundPath == 2){ //其它退款路径需处理
            // 获取账户类型
            Integer srAccountType = serviceRefunds.getSrAccountType();
            if (srAccountType == null){
                throw new RRException("请选择账户类型!");
            }

            if(srAccountType == 1){// 银行卡
                String srBankCode = serviceRefunds.getSrBankCode();
                String srBankCardholder = serviceRefunds.getSrBankCardholder();
                String srBankName = serviceRefunds.getSrBankName();
                String srBankOpen = serviceRefunds.getSrBankOpen();

                if (StringUtil.isEmpty(srBankCode)||StringUtil.isEmpty(srBankCardholder)||StringUtil.isEmpty(srBankName)||
                        StringUtil.isEmpty(srBankOpen)){
                    throw new RRException("请填写完整的银行卡相关信息!");
                }

            }else if (srAccountType == 2) {// 支付宝
                String srAlipayCode = serviceRefunds.getSrAlipayCode();
                String srAlipayName = serviceRefunds.getSrAlipayName();

                if (StringUtil.isEmpty(srAlipayCode)||StringUtil.isEmpty(srAlipayName)){
                    throw new RRException("请填写完整的支付宝相关信息!");
                }
            }
        }
    }

    /**
     * 处理售后退货信息
     * @param serviceRegisterTemp
     * @param erpOrderItemList
     * @return
     */
    private List<ServiceReceiveGoodsEntity> serviceReceiveGoods(ServiceRegisterEntity serviceRegisterTemp, List<ErpOrderItemEntity> erpOrderItemList){
        //处理收货商品信息
        if (erpOrderItemList.size() == 0){
            throw new RRException("请选择退货商品!");
        }

        List<ServiceReceiveGoodsEntity> serviceReceiveGoodsList = new ArrayList<ServiceReceiveGoodsEntity>();
        //循环组装退货商品
        for (ErpOrderItemEntity erpOrderItem : erpOrderItemList){
            ServiceReceiveGoodsEntity serviceReceiveGoodsTemp = new ServiceReceiveGoodsEntity();
            serviceReceiveGoodsTemp.setSrgSrId(serviceRegisterTemp.getSrId());
            serviceReceiveGoodsTemp.setSrgStatus(0);
            serviceReceiveGoodsTemp.setSrgProductId(erpOrderItem.getProductId());
            serviceReceiveGoodsTemp.setSrgGoodsName(erpOrderItem.getName());
            serviceReceiveGoodsTemp.setSrgQuantity(erpOrderItem.getNums());
            serviceReceiveGoodsTemp.setSrgStockId(serviceRegisterTemp.getSrReturnStockId());
            serviceReceiveGoodsTemp.setSrgDel(0);
            serviceReceiveGoodsTemp.setSrgCreateName(serviceRegisterTemp.getSrCreateName());
            serviceReceiveGoodsTemp.setSrgCreateTime(new Date());
            serviceReceiveGoodsList.add(serviceReceiveGoodsTemp);
        }

        return serviceReceiveGoodsList;
    }

}
